﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="Task_When_GetError.cs" company="JDML Consulting Ltd.">
//   Copyright 2011 Photon Project - http://photon.codeplex.com
// </copyright>
// <summary>
//   Defines the Task_When_GetError type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace Photon.Threading
{
    using System;
    using System.Threading;
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    using Testing.Threading;

    [TestClass]
   public class Task_When_GetError : AsynchronousTest
   {
      [TestMethod]
      [HostType("CHESS")]
      public void If_Completed_And_Task_Returns_Should_Callback_With_Null()
      {
         var result = string.Empty;
         Task.Factory.From(() => TestStrings.Failure)
            .Start(t => result = t.Error != null ? TestStrings.Failure : TestStrings.Success);
         AsyncUtility.SleepUntil(() => result != string.Empty);
         Assert.AreEqual(TestStrings.Success, result);
      }

      [TestMethod]
      [HostType("CHESS")]
      public void If_Completed_And_Task_Throws_Should_Callback_With_Exception()
      {
         var result = string.Empty;
         Task.Factory.From(() => { throw new Exception(TestStrings.Success); })
            .Start(t => result = t.Error != null ? t.Error.Message : TestStrings.Failure);
         AsyncUtility.SleepUntil(() => result != string.Empty);
         Assert.AreEqual(TestStrings.Success, result);
      }

      [TestMethod]
      [HostType("CHESS")]
      public void If_Started_And_Not_Complete_And_Task_Returns_Should_Block_Until_Is_Complete_And_Return_Null()
      {
         var thread = Thread.CurrentThread;
         var task = Task.Factory.From(
            () =>
               // This line is probably not required now CHESS has been added
               AsyncUtility.SleepUntilThreadIsInState(thread, ThreadState.WaitSleepJoin));
         task.Start();
         // access result, should go into Wait state and release task for completion.
         Assert.IsNull(task.Error);
      }

      [TestMethod]
      [HostType("CHESS")]
      public void If_Started_And_Not_Complete_And_Task_Throws_Should_Block_Until_Is_Complete_And_Return_Exception()
      {
         var thread = Thread.CurrentThread;
         Func<int> taskFunc = () =>
            {
               // This line is probably not required now CHESS has been added
               AsyncUtility.SleepUntilThreadIsInState(thread, ThreadState.WaitSleepJoin);
               throw new Exception(TestStrings.Success);
            };
         var task = Task.Factory.From(taskFunc);
         task.Start();
         // access result, should go into Wait state and release task for completion.
         Assert.IsNotNull(task.Error);
         Assert.AreEqual(TestStrings.Success, task.Error.Message);
      }

      [TestMethod]
      [HostType("CHESS")]
      public void If_Is_Not_Started_Should_Block_Until_Started_And_Completed()
      {
         var thread = Thread.CurrentThread;

         var task = Task.Factory.From(() => { throw new Exception(TestStrings.Success); });
         ThreadPool.QueueUserWorkItem(s =>
         {
            // This line is probably not required now CHESS has been added
            AsyncUtility.SleepUntilThreadIsInState(thread, ThreadState.WaitSleepJoin);
            task.Start();
         });
         Assert.IsNotNull(task.Error);
         Assert.AreEqual(TestStrings.Success, task.Error.Message);
      }
   }
}
